/*
 * 代号：凤凰
 * http://www.jphenix.org
 * 2014-06-04
 * V4.0
 */
package com.jphenix.kernel.objectloader.util;

import com.jphenix.kernel.objectloader.exception.BeanException;
import com.jphenix.kernel.objectloader.interfaceclass.IBeanFactoryManager;
import com.jphenix.share.lang.*;
import com.jphenix.share.tools.JavacTool;
import com.jphenix.share.util.*;
import com.jphenix.standard.docs.ClassInfo;

import java.io.File;
import java.io.FileOutputStream;
import java.io.PrintStream;
import java.lang.reflect.Method;
import java.net.URL;
import java.util.ArrayList;
import java.util.HashMap;

/**
 * 影子类实例处理类
 * 
 * 2019-04-09 用SDouble替代了SFloat
 * 2019-07-20 优化了代码
 * 
 * @author 刘虻
 * 2010-4-29 上午11:09:35
 */
@ClassInfo({"2019-07-20 15:29","影子类实例处理类"})
public class ShadowBeanUtil {

	/**
	 * 基本类型
	 */
	protected final String checkBaseTypeString = 
						"int,long,double,byte,char,boolean,float,";
	
	protected boolean deleteSourceFile = false;			//在生成class后是否删除源文件

	protected Class<?> sourceInterface = null;				//目标接口
	
	protected String
				encoding = null							//类内容编码格式
				,localPackage = null					//当前包路径
				,className = null						//部署的类名
				,implFileName = null					//部署文件名(无扩展名)
				,implClassFilePath = null				//部署类文件路径
				,webInfPath = null						//WEB-INF路径
				,implClassPath = null;					//部署类路径
	
	protected StringBuffer 
					fieldSbf = new StringBuffer()		//引用类
					,methodSbf = new StringBuffer()		//实现接口名称
					,initSbf = new StringBuffer();		//调用方法
	
	protected ArrayList<String> importArrl = new ArrayList<String>();	//引用信息序列
	
	protected HashMap<String,String> checkMethodHasm = null;			//检测方法是否重复容器
	protected Object srcBean = null;					//原型类实例
	protected ArrayList<String> classPathList = null;			//类路径序列
	protected IBeanFactoryManager bf = null;			//类工厂管理类
	
	/**
	 * 构造函数
	 * @author 刘虻
	 */
	public ShadowBeanUtil(IBeanFactoryManager bf) {
		super();
		this.bf = bf;
	}
	
	/**
	 * 获取有效的类路径序列
	 * 刘虻
	 * 2010-9-5 上午10:21:59
	 * @return 有效的类路径序列
	 */
	protected ArrayList<String> getClassPathList() {
		if(classPathList==null) {
			classPathList = new ArrayList<String>();
		}
		return classPathList;
	}
	
	
	/**
	 * 获取类内容编码格式
	 * 刘虻
	 * 2010-4-29 下午02:47:18
	 * @return 类内容编码格式
	 */
	public String getEncoding() {
		if(encoding==null) {
			encoding = "UTF-8";
		}
		return encoding;
	}
	
	/**
	 * 设置类内容编码格式
	 * 刘虻
	 * 2010-4-29 下午02:47:26
	 * @param encoding 类内容编码格式
	 */
	public void setEncoding(String encoding) {
		this.encoding = encoding;
	}
	
	
	/**
	 * 设置在生成class后是否删除源文件
	 * 刘虻
	 * 2010-4-29 下午02:46:07
	 * @param deleteSourceFile 在生成class后是否删除源文件
	 */
	public void setDeleteSourceFile(boolean deleteSourceFile) {
		this.deleteSourceFile = deleteSourceFile;
	}
	
	
	/**
	 * 获取影子类实例
	 * 刘虻
	 * 2010-4-29 下午12:49:05
	 * @param bean 原型类
	 * @param interfaceCls 执行符合的接口
	 * @param webInfPath WEB-INF文件夹
	 * @return 符合接口的类实例
	 * @throws Exception 执行发生异常
	 */
	public <T> T getShadowObject(
			T bean
			,Class<?> interfaceCls
			,String webInfPath) throws Exception {
		if(bean==null) {
			throw new BeanException(
					"Deploy Shadow Class Not Find The Bean Object");
		}
		if(interfaceCls==null) {
			throw new BeanException(
					"Deploy Shadow Class The Interface Is Null");
		}
		if(webInfPath==null || webInfPath.length()<1) {
			throw new BeanException(
				"Deploy Shadow Class The WEB-INF Path Is Null");
		}
		srcBean = bean;
		sourceInterface = interfaceCls;
		this.webInfPath = webInfPath;
		//获取包路径
		localPackage = sourceInterface.getPackage().getName();
		//构造部署类路径
		implClassPath = sourceInterface.getName()+"_client";
		//获取部署类文件名
		implFileName = 
			implClassPath.substring(
					implClassPath.lastIndexOf(".")+1
			);
		//部署类文件所在路径
		implClassFilePath = webInfPath+"/classes/"+BaseUtil.swapString(localPackage,".","/");
		
		//类文件路径
		String classFilePath = implClassFilePath+"/"+implFileName+".class";
		if((new File(classFilePath)).exists()) {
			//获取返回值
			T reObj = getShadowObject(true);
			if(reObj!=null) {
				return reObj;
			}
			//返回值为空，说明返回的类版本号比接口旧
		}
		//放入基本类路径,在buildSourceFile时，会加入引用类所在的类路径
		ClassLoaderUtil
			.getUrlClassLoaderPath(
					interfaceCls.getClassLoader(),getClassPathList());
		//生成源文件
		buildSourceFile();
		//构造返回值
		StringBuffer reSbf = new StringBuffer();
		for(String res:getClassPathList()) {
			if(res==null) {
				continue;
			}
			reSbf.append(res).append(File.pathSeparator);
		}
		
		//源文件路径
		String javaFilePath = implClassFilePath+"/"+implFileName+".java";
		//执行编译
		(new JavacTool()).compileJavaFile(
				javaFilePath
				,webInfPath+"/classes"
				,getEncoding()
				,reSbf.toString());
		if (deleteSourceFile) {
			(new File(javaFilePath)).delete();
		}
		//类文件对象
		File classFile = new File(classFilePath);
		if(classFile.exists()) {
			bf.addNewSource((new File(webInfPath+"/classes")).getPath(),classFile);
		}
		return getShadowObject(false);
	}
	
	/**
	 * 获取类头信息
	 * @author 刘虻
	 * 2010-4-29 下午06:40:31
	 * @return 类头信息
	 */
	protected String getHeadInfo() {
		return "/*\n * Code：Phenix\n * Server Auto Complete Class\n * "+SDate.nowDateString()+"\n * VER 3.0\n */\n ";
	}
	
	/**
	 * 生成源文件
	 * 刘虻
	 * 2010-4-29 下午06:40:31
	 * @throws Exception 执行发生异常
	 */
	protected void buildSourceFile() throws Exception {
		//添加固定引用
		appendImport("java.lang.reflect.Method");
		//添加接口路径引用
		if(!isLocalPackage(sourceInterface)) {
			appendImport(sourceInterface.getName());
		}
		//添加接口路径引用
		if(!isLocalPackage(ShadowBeanParent.class)) {
			appendImport(ShadowBeanParent.class.getName());
		}
		//初始化接口中的方法
		initInterface();
		//保存文件路径
		String saveFilePath = implClassFilePath+"/"+implFileName+".java";
		//建立源文件
		File saveFile = new File(saveFilePath);
		if(saveFile.exists()) {
			saveFile.delete();
		}
		//如果目标路径都没有，该方法可以建立路径
		saveFile = SFilesUtil.createFile(saveFilePath);
		//获取文件输出流
		PrintStream savePris = null;
		try {
			savePris =
	            new PrintStream(
	           		 new FileOutputStream(saveFile,true)
	           		 ,true
	           		 ,getEncoding());
        
			savePris.println(getHeadInfo()); //输出头
			//添加包名
			savePris.println("package "+localPackage+";\n");
			//添加引用类路径
			for(int i=0;i<importArrl.size();i++) {
				savePris.println("import "+importArrl.get(i)+";");
			}
			savePris.println("import com.jphenix.standard.docs.*;\n");
			
			//添加类说明
			savePris.print(getClassInfo());
			
			//类信息数组
			String[] clsInfos = ClassUtil.getClassInfo(sourceInterface);
			
			savePris.print("@ClassInfo({\""+clsInfos[0]+"\",\""+clsInfos[1]+"-影子类\"})\n");
			
			//类信息数组
			String[] beanInfos = ClassUtil.getBeanInfo(sourceInterface);
			savePris.print("@BeanInfo({\""+beanInfos[0]+"\"})");
			
			//添加类头
			savePris.print(getClassHead());

			//添加方法变量信息
			savePris.print(fieldSbf);
			//添加构造函数
			savePris.print(getConstructorInfo());
			//添加方法信息
			savePris.print(methodSbf);
			//添加初始化方法
			savePris.println(getMethodInfo());
			savePris.println("	public void _init() throws Exception {");
			savePris.print(initSbf);
			savePris.println("	}");
			savePris.print("}"); //类结束
		}catch(Exception e) {
			throw e;
		}finally {
			try {
				savePris.close();
			}catch(Exception e2) {}
		}
	}
	
	
	/**
	 * 获取类头信息
	 * @author 刘虻
	 * 2010-4-29 下午05:17:46
	 * @return 类头信息
	 */
	protected StringBuffer getClassHead() {
		//构建返回值
		StringBuffer reSbf = new StringBuffer();
		reSbf
			.append("public class ")
			.append(implFileName)
			.append(" extends ShadowBeanParent")
			.append(" implements ")
			.append(getClassName(sourceInterface.getName()))
			.append(" {\n\n");
		return reSbf;
	}
	
	/**
	 * 获取类信息
	 * @author 刘虻
	 * 2010-4-29 下午05:17:46
	 * @return 类信息
	 */
	protected String getClassInfo() {
		return "\n\n/**\n * Auto Deploy Cover Interface "+getClassName(sourceInterface.getName())+" Shadow\n * "
		+" * @author machine\n * "
		+SDate.nowDateTimeString()+"\n */\n";
	}
	
	/**
	 * @deprecated 内部调用
	 * 
	 * 如果第一次构建Class与接口进行VER比较后发现不一致，返回空
	 * 在重新部署class后再次调用该方法，再一次构建Class时，获取到的VER值
	 * 仍然是部署前的VER值，导致重新部署后（部署时就已经同步了Class与接口的VER值）
	 * 发现仍然不一致继续返回空，最后抛空指针错误
	 * 
	 * 针对以上问题，还没有找到更好的解决办法，第一次构建的Class的Hash值与部署后的的确
	 * 不同，但前后获取到的VER Field对象的Hash值相同，也就是说，虽然部署前后将VER值改变
	 * 了，但后一次获取到的Field还是上一次的（不是新的），无法重新加载VER Field
	 * 
	 * 获取影子类实例
	 * 刘虻
	 * 2010-4-29 下午05:17:46
	 * @param checkVer 是否检测版本号
	 * @return 影子类实例
	 * @throws Exception 执行发生异常
	 */
	@SuppressWarnings("unchecked")
	protected <T> T getShadowObject(boolean checkVer) throws Exception {
		//构建返回对象类
		Class<T> reCls = null;
		try {
			reCls = (Class<T>)bf.getClassLoader().loadClass(implClassPath);
		}catch(Exception e) {
			throw new BeanException("getShadowObject Exception:"+DebugUtil.outException(e));
		}
		if(checkVer && !ClassUtil.getClassInfo(sourceInterface)[0].equals(ClassUtil.getClassInfo(reCls)[0])) {
			//如果接口版本号与部署影子类版本号不同
			return null;
		}
		//构建返回对象
		T reObj = reCls.newInstance();
		//构建设置原型类方法
		Method setBeanMethod = null;
		try {
			setBeanMethod = 
				reCls.getMethod("_setObject", Object.class);
		}catch(Exception e) {
			throw new BeanException("getShadowObject Get Shadow Object _setObject Method Exception:"+DebugUtil.outException(e));
		}
		//设置原型类 设置原型类的同时会检查接口与原型类中对应的方法是否匹配
		setBeanMethod.invoke(reObj, srcBean);
		return reObj;
	}
	
	
	

	/**
	 * 初始化接口中的方法
	 * 刘虻
	 * 2010-4-29 下午05:29:29
	 * @throws Exception 执行发生异常
	 */
	protected void initInterface() throws Exception {
		
		//获取该类中所有的方法
		Method[] methods = sourceInterface.getMethods();
		if (methods==null) {
			return;
		}
		//循环方法处理
		for (int i=0;i<methods.length;i++) {
			if (methods[i]==null) {
				continue;
			}
			initMethod(methods[i],i);
		}
	}
	
	
	/**
	 * 获取类路径，getClass如果返回数组格式的类路径，则返回元素类路径
	 * 如果是基本类型数组，则返回空字符串
	 * 刘虻
	 * 2010-8-3 下午07:11:09
	 * @param classPath 待处理的类路径
	 * @return 处理后的类路径
	 */
	protected String getClassPath(String classPath) {
		String checkStr = classPath;
		int level = 0; //数组层级
		while(checkStr.startsWith("[")) {
			level++;
			checkStr = checkStr.substring(1);
		}
		if(level>0) {
			//去掉数组类型标识字母
			checkStr = checkStr.substring(1);
		}
		if(checkStr.endsWith(";")) {
			checkStr = checkStr.substring(0,checkStr.length()-1);
		}
		return checkStr;
	}
	
	
	/**
	 * 根据类路径返回类名
	 * @author 刘虻
	 * 2010-4-29 下午05:29:29
	 * @param classPath 类路径
	 * @return 类名
	 */
	protected String getClassName(String classPath) {
		String checkStr = classPath;
		int level = 0; //数组层级
		while(checkStr.startsWith("[")) {
			level++;
			checkStr = checkStr.substring(1);
		}
		String cHead = checkStr; //类名头
		if(level>0) {
			if ("I".equals(checkStr)) {
				cHead = "int";
			}else if ("J".equals(checkStr)) {
				cHead = "long";
			}else if ("Z".equals(checkStr)) {
				cHead = "boolean";
			}else if ("B".equals(checkStr)) {
				cHead = "byte";
			}else if ("C".equals(checkStr)) {
				cHead = "char";
			}else if ("F".equals(checkStr)) {
				cHead = "float";
			}else if ("D".equals(checkStr)) {
				cHead = "double";
			}else {
				//不是基本类型 头一个字母为L 结尾为分号结束
				int point = checkStr.lastIndexOf(".");
				if(point>-1) {
					cHead = checkStr.substring(point+1);
				}else {
					cHead = checkStr;
				}
				if(cHead.endsWith(";")) {
					cHead = cHead.substring(0,cHead.length()-1);
				}
			}
		}else {
			//不是基本类型 头一个字母为L 结尾为分号结束
			int point = checkStr.lastIndexOf(".");
			if(point>-1) {
				cHead = checkStr.substring(point+1);
			}else {
				cHead = checkStr;
			}
			if(cHead.endsWith(";")) {
				cHead = cHead.substring(0,cHead.length()-1);
			}
		}
		for(int i=0;i<level;i++) {
			cHead += "[]";
		}
		return cHead;
	}
	
	
	/**
	 * 判断类是否为当前包
	 * @author 刘虻
	 * 2010-4-29 下午05:29:29
	 * @param cls 指定类
	 * @return true当前包
	 */
	protected boolean isLocalPackage(Class<?> cls) {
		if (cls==null ) {
			return true;
		}
		if ((localPackage==null 
				|| localPackage.length()<1) 
			&& (cls.getPackage()==null 
					|| cls.getPackage().getName()==null 
					|| cls.getPackage().getName().length()==0)) {
			return true;
		}
		if (localPackage!=null 
				&& localPackage.length()>0 
				&& cls.getPackage()!=null 
				&& cls.getPackage().getName()!=null 
				&& cls.getPackage().getName().length()>0) {
			return localPackage.equals(cls.getPackage().getName());
		}
		return false;
	}
	
	
	/**
	 * 获取方法信息
	 * @author 刘虻
	 * 2010-4-29 下午05:29:29
	 * @return 方法信息
	 */
	protected String getMethodInfo() {
		return "	/**\n	 * Overlay Method\n	 * @author machine\n	 * "+SDate.nowDateTimeString()+"\n	 */";
	}

	/**
	 * 获取构造函数信息
	 * @author 刘虻
	 * 2010-4-29 下午05:29:29
	 * @return 构造函数信息
	 */
	protected String getConstructorInfo() {
		return "\n	/**\n	 * Construct Function\n	 * "+SDate.nowDateTimeString()+"\n	 */\n	public "+implFileName+"() {\n		super();\n	}\n\n";
	}
	
	/**
	 * 构造方法内容
	 * @author 刘虻
	 * 2010-4-29 下午05:29:29
	 * @param method 方法
	 * @param index 方法索引，防止重复
	 * @throws Exception 执行发生异常
	 */
	protected void initMethod(Method method,int index) throws Exception {

		Class<?>[] exceptionClsses = method.getExceptionTypes(); //方法抛出的异常类数组
		Class<?> returnClass = method.getReturnType(); //返回值类
		Class<?>[] paraClasses = method.getParameterTypes(); //传入参数类数组
		String methodName = method.getName(); //方法名
		
		//部署后的方法对象名 如果方法名相同，参数不同，就会出问题，所以需要在后面加上索引
		String implMethodName = methodName+"_method_"+index;
		
		//插入字段声明
		fieldSbf
			.append("	protected Method ")
			.append(implMethodName)
			.append(" = null; //For Method ")
			.append(methodName)
			.append("\n");
		
		/*
		 * 构造初始化方法内容
		 */
		initSbf
			.append("		try {\n			")
			.append(implMethodName)
			.append(" = \n")
			.append("				_bean.getClass()\n")
			.append("					.getMethod(\n")
			.append("							\"")
			.append(methodName)
			.append("\"\n")
			.append("							,new Class[] {");
		for (int i=0;i<paraClasses.length;i++) {
			if (i>0) {
				initSbf.append(", ");
			}
			initSbf.append(getClassName(paraClasses[i].getName())).append(".class");
		}
		initSbf
			.append("});\n")
			.append("		}catch(Exception e) {\n")
			.append("			e.printStackTrace();\n")
			.append("			//Build Error Msg\n")
			.append("			StringBuffer errorSbf = new StringBuffer();\n")
			.append("			errorSbf\n")
			.append("				.append(\"Get Method Exception Bean ID:[\")\n")
			.append("				.append(BEAN_ID)\n")
			.append("				.append(\"] Facotry ID:[\")\n")
			.append("				.append(FACTORY_ID)\n")
			.append("				.append(\"] Method:[")
			.append(methodName)
			.append("] Exception:[\")\n")
			.append("				.append(e)\n")
			.append("				.append(\"]\");\n")
			.append("			throw new Exception(errorSbf.toString());\n")
			.append("		}\n");
			
		methodSbf
			.append(getMethodInfo())
			.append("\n	public ");
		
		String resTypeName = null; //返回值类型
		if (returnClass==null) {
			methodSbf.append("void");
			resTypeName = "";
		}else {
			resTypeName = returnClass.getName(); //返回值类型
			methodSbf.append(getClassName(resTypeName));
			if (!isLocalPackage(returnClass)) {
				appendImport(resTypeName);
			}
		}
		//构造参数段
		methodSbf.append(" ").append(methodName).append("(");
		if (paraClasses!=null) {
			for (int i=0;i<paraClasses.length;i++) {
				if (!isLocalPackage(paraClasses[i])) {
					appendImport(paraClasses[i].getName());
				}
				if (i>0) {
					methodSbf.append(", ");
				}
				methodSbf.append(getClassName(paraClasses[i].getName()))
					 .append(" arg").append(i);
			}
		}
		methodSbf.append(") ");
		
		//构造异常段
		if (exceptionClsses!=null && exceptionClsses.length>0) {
			methodSbf.append("throws ");
			for (int i=0;i<exceptionClsses.length;i++) {
				if (!isLocalPackage(exceptionClsses[i])) {
					appendImport(exceptionClsses[i].getName());
				}
				if (i>0) {
					methodSbf.append(", ");
				}
				methodSbf.append(getClassName(exceptionClsses[i].getName()));
			}
		}
		methodSbf.append("{\n		try {\n");
		//方法体
		if (returnClass!=null && !"void".equals(resTypeName)) {
			//带返回值
			methodSbf
				.append("			//Build Return Vlaue\n			Object reObj =\n				")
				.append(implMethodName)
				.append(".invoke(_bean,new Object[] {");
		}else {
			methodSbf
				.append("			")
				.append(implMethodName)
				.append(".invoke(_bean,new Object[] {");
		}
		for (int i=0;i<paraClasses.length;i++) {
			if (i>0) {
				methodSbf.append(", ");
			}
			methodSbf.append(getFixObject("arg"+i,paraClasses[i].getName()));
		} 
		methodSbf.append("});\n");
		if (returnClass!=null && !"void".equals(resTypeName)) {
			if (checkBaseTypeString.indexOf(resTypeName+",")>-1) {
				if ("boolean".equals(resTypeName)) {
					appendImport(SBoolean.class.getName());
					methodSbf.append("			return (reObj==null)?false:SBoolean.valueOf(reObj);\n");
				}else if ("int".equals(resTypeName)) {
					appendImport(SInteger.class.getName());
					methodSbf.append("			return (reObj==null)?0:SInteger.valueOf(reObj);\n");
				}else if ("long".equals(resTypeName)) {
					appendImport(SLong.class.getName());
					methodSbf.append("			return (reObj==null)?0:SLong.valueOf(reObj);\n");
				}else if ("float".equals(resTypeName)) {
					appendImport(SDouble.class.getName());
					methodSbf.append("			return (reObj==null)?0:(float)SDouble.valueOf(reObj);\n");
				}else if ("double".equals(resTypeName)) {
					appendImport(SDouble.class.getName());
					methodSbf.append("			return reObj==null)?0:SDouble.valueOf(reObj);\n");
				}else if ("byte".equals(resTypeName)) {
					appendImport(SString.class.getName());
					methodSbf.append("			reObj = SString.value(reObj);\n");
					methodSbf.append("			return reObj.equals(\"\")?0:((String)reObj).getBytes()[0];\n");
				}else if ("char".equals(resTypeName)) {
					appendImport(SString.class.getName());
					methodSbf.append("			reObj = SString.value(reObj);\n");
					methodSbf.append("			return reObj.equals(\"\")?0:((String)reObj).charAt(0);\n");
				}
			}else {
				methodSbf
					.append("			return (")
					.append(getClassName(resTypeName))
					.append(")reObj;\n");
			}
		}
		methodSbf.append("		}catch(Exception e) {\n");
		if (exceptionClsses!=null && exceptionClsses.length>0) {
			for (int i=0;i<exceptionClsses.length;i++) {
				//异常类名
				String exceptionName = 
					getClassName(exceptionClsses[i].getName());
				methodSbf
					.append("			if(e instanceof ")
					.append(exceptionName)
					.append(") {\n				throw (")
					.append(exceptionName)
					.append(")e;\n			}\n");
			}
		}
		methodSbf
			.append("			e.printStackTrace();\n")
			.append("			//Build Error Msg\n")
			.append("			StringBuffer errorSbf = new StringBuffer();\n")
			.append("			errorSbf\n")
			.append("				.append(\"Invoke Bean ID:[\")\n")
			.append("				.append(BEAN_ID)\n")
			.append("				.append(\"] Facotry ID:[\")\n")
			.append("				.append(FACTORY_ID)\n")
			.append("				.append(\"] Method:[")
			.append(methodName)
			.append("] Exception:[\")\n")
			.append("				.append(e)\n")
			.append("				.append(\"]\");\n")
			.append("			System.err.print(errorSbf);\n")
			.append("			throw new RuntimeException(errorSbf.toString());\n")
			.append("		}\n")
			.append("	}\n\n");
	}
	
	
	/**
	 * 整理参数值 主要整理基本类型
	 * @author 刘虻
	 * 2010-4-29 下午03:46:05
	 * @param objName 参数值名
	 * @param objType 参数类型
	 * @return 整理后的参数值
	 */
	protected String getFixObject(String objName,String objType) {
		if (checkBaseTypeString.indexOf(objType+",")>-1) {
			if ("boolean".equals(objType)) {
				return "new Boolean("+objName+")";
			}else if ("int".equals(objType)) {
				return "new Integer("+objName+")";
			}else if ("long".equals(objType)) {
				return "new Long("+objName+")";
			}else if ("float".equals(objType)) {
				return "new Float("+objName+")";
			}else if ("double".equals(objType)) {
				return "new Double("+objName+")";
			}else if ("byte".equals(objType)) {
				return "new Byte("+objName+")";
			}else if ("char".equals(objType)) {
				return "new Integer("+objName+")";
			}else {
				return objName;
			}
		}else {
			return objName;
		}
	}
	
	/**
	 * 添加引用
	 * @author 刘虻
	 * 2010-4-29 下午03:46:05
	 * @param classPath 引用类路径
	 */
	protected void appendImport(String classPath) {
		classPath = getClassPath(classPath); //处理数组类型 如： [Ljava.lang.String;
		if (checkBaseTypeString.indexOf(classPath+",")<0) {
			if (classPath.startsWith("[")) {
				if (classPath.length()==2) {
					return;
				}
				classPath = classPath.substring(2,classPath.length()-1);
			}
			if (!importArrl.contains(classPath) 
						&& !"void".equals(classPath)) {
				importArrl.add(classPath);
			}
			
			//判断加入类路径
			URL classPathUrl = 
				getClass()
					.getClassLoader()
						.getResource("/"+classPath.replaceAll("\\.","/")+".class");
			//java.lang 之类的，返回的源路径为空
			if(classPathUrl!=null) {
				//类所属的根类路径
				String cp = classPathUrl.getPath();
				//判断该类是否在jar包内
				int point = cp.indexOf("!/");
				if(point>-1) {
					cp = cp.substring(0,point);
				}
				if(!getClassPathList().contains(cp)) {
					getClassPathList().add(cp);
				}
			}
			
		}
	}
}
